package both.map.mapModel;
import both.map.*;
/**
 * Cell content which is terrain
 * 
 * @author jdl
 */
public class TerrainCell extends ModelCell {
	
	private TerrainType terrain;
	
	/**
	 * Construct a new TerrainCell, with a given terrain type.
	 * 
	 * @param type the type of terrain to be used in this content
	 */
	public TerrainCell(TerrainType type)
	{
		this(type, false);
	}
	
	/**
	 * Construct a new TerrainCell, specifying whether the TerrainCell
	 * is for a normal map or for a map (affects mutability.
	 */
	private TerrainCell(TerrainType type, boolean forUpdate)
	{
		super(forUpdate);
		terrain = type;
	}
	
	/**
	 * Construct a new TerrainCell, with empty terrain.
	 */
	public TerrainCell()
	{
		this(TerrainType.empty);
	}
	
	/**
	 * @return the type of this terrain
	 */
	public TerrainType getTerrainType()
	{
		return terrain;
	}
	
	/**
	 * change the type of terrain stored in this content
	 * @param newTerrain the new terrain type to be stored here
	 * @return true if successful, false if unsuccessful (i.e. this is part of an update)
	 */
	public boolean reassignTerrain(TerrainType newTerrain)
	{
		if (!isPartOfUpdate()) {
			terrain = newTerrain;
			flagForUpdate();
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * @return the update of this cell; i.e a copy of the cell if
	 * it needs updating, or null if not.
	 */
	@Override
	public TerrainCell grabUpdate()
	{
		if (hasBeenUpdated()) {
			resetUpdate();
			return new TerrainCell(terrain, true);
		} else {
			return null;
		}
	}
	
	/**
	 * Apply an updated TerrainCell to this one
	 * @param updateCell the cell to update this one with
	 * @throws IllegalArgumentException if the update is not of the same type as this one
	 */
	public void applyUpdate(ModelCell updateCell)
		throws IllegalArgumentException
	{
		if (updateCell != null) {
			if (!(updateCell instanceof TerrainCell)) {
				throw new IllegalArgumentException("Update passed to " + toString() + " was not a  TerrainCell");
			}
		
			TerrainCell update = (TerrainCell) updateCell;
			reassignTerrain(update.getTerrainType());
		}
	}
}
